﻿using System;
using System.Threading.Tasks;
using K9Nano.Share.Exceptions;

namespace K9Nano.Configuration
{
    public interface ISettingManager
    {
        /// <summary>
        /// Get setting value for Current user
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        ValueTask<string> GetSettingValueAsync(string name);

        /// <summary>
        /// Get setting value for specific tenant and user
        /// </summary>
        /// <param name="name"></param>
        /// <param name="tenantId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        ValueTask<string> GetSettingValueAsync(string name, Guid? tenantId, Guid? userId);

        /// <summary>
        /// Change setting value for Current user
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        ValueTask ChangeSettingAsync(string name, string value);

        /// <summary>
        /// Change setting value for specific tenant and user
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="tenantId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        ValueTask ChangeSettingAsync(string name, string value, Guid? tenantId, Guid? userId);

        public ValueTask<string> GetSettingValueForApplicationAsync(string name)
        {
            return GetSettingValueAsync(name, null, null);
        }

        public ValueTask<string> GetSettingValueForTenantAsync(string name, Guid tenantId)
        {
            return GetSettingValueAsync(name, tenantId, null);
        }

        public ValueTask<string> GetSettingValueForUserAsync(string name, Guid userId)
        {
            return GetSettingValueAsync(name, null, userId);
        }

        public ValueTask ChangeSettingForApplicationAsync(string name, string value)
        {
            return ChangeSettingAsync(name, value, null, null);
        }

        public ValueTask ChangeSettingForTenantAsync(string name, string value, Guid tenantId)
        {
            return ChangeSettingAsync(name, value, tenantId, null);
        }

        public ValueTask ChangeSettingForUserAsync(string name, string value, Guid userId)
        {
            return ChangeSettingAsync(name, value, null, userId);
        }

        public async ValueTask<int> GetIntAsync(string name)
        {
            var value = await GetSettingValueAsync(name);
            if (int.TryParse(value, out var i))
            {
                return i;
            }
            throw new K9Exception($"Can not parse value ({value}) of setting ({name}) to int");
        }

        public async ValueTask<long> GetLongAsync(string name)
        {
            var value = await GetSettingValueAsync(name);
            if (long.TryParse(value, out var i))
            {
                return i;
            }
            throw new K9Exception($"Can not parse value ({value}) of setting ({name}) to long");
        }

        public async ValueTask<bool> GetBooleanAsync(string name)
        {
            var value = await GetSettingValueAsync(name);
            if (bool.TryParse(value, out var i))
            {
                return i;
            }
            throw new K9Exception($"Can not parse value ({value}) of setting ({name}) to boolean");
        }
    }
}